/******************************************************************************
 * Copyright (C) 2015  671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#ifndef NODECPP_DATA_REL_SQLOPERATION_H_
#define NODECPP_DATA_REL_SQLOPERATION_H_

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

#include <string>
#include <vector>
#include <NodeCpp/AutoPtr.h>
#include <NodeCpp/LockedQueue.h>
#include <NodeCpp/Data/Rel/Callbacks.h>

namespace NodeCpp {
namespace Data {
namespace Rel {
    class SqlConnection;
    class SqlStmtParameters;
    class SqlDelayThread;

    class SqlOperation
    {
    public:
        virtual ~SqlOperation(){}
        virtual bool Execute(SqlConnection *) = 0;
    };

    class SqlPreparedRequest : public SqlOperation
    {
    public:
        SqlPreparedRequest(int _Index, SqlStmtParameters* _Arg);
        virtual ~SqlPreparedRequest(void);

        bool Execute(SqlConnection* _Conn) override;

    private:
        const int Index_;
        AutoPtr<SqlStmtParameters> Param_;
    };


    class SqlResultQueue : public LockedQueue<IQueryCallback*>
    {
    public:
        SqlResultQueue(void) {}
        void Update(void);
    };

    class SqlQuery : public SqlOperation
    {
    public:
        SqlQuery(const char* _Sql, IQueryCallback* _Callback, SqlResultQueue* _Queue)
            : Sql_(_Sql), Callback_(_Callback), Queue_(_Queue) {}
        ~SqlQuery(void) {  }
        bool Execute(SqlConnection* _Conn) override;

    private:
        const std::string Sql_;
        IQueryCallback* Callback_;
        SqlResultQueue* Queue_;
    };

    class SqlQueryHolder
    {
        friend class SqlQueryHolderEx;
    private:
        typedef std::pair<std::string, QueryResult*> SqlResultPair;
        std::vector<SqlResultPair> Queries_;
    public:
        SqlQueryHolder(void) {}
        ~SqlQueryHolder(void);
        bool SetQuery(std::size_t _Index, const char* _Sql);
        bool SetPQuery(std::size_t _Index, const char* _Format, ...);
        void SetSize(std::size_t _Size);
        QueryResult* GetResult(std::size_t _Index);
        void SetResult(std::size_t _Index, QueryResult* _Result);
        bool Execute(IQueryCallback* _Callback, SqlDelayThread* _Thread, SqlResultQueue* _Queue);
    };

    class SqlQueryHolderEx : public SqlOperation
    {
    private:
        SqlQueryHolder* Holder_;
        IQueryCallback* Callback_;
        SqlResultQueue* Queue_;
    public:
        SqlQueryHolderEx(SqlQueryHolder* _Holder, IQueryCallback* _Callback, SqlResultQueue* _Queue)
            : Holder_(_Holder), Callback_(_Callback), Queue_(_Queue) {}
        bool Execute(SqlConnection* _Conn) override;
    };
}}}

#endif // NODECPP_DATA_REL_SQLOPERATION_H_
